
from PIL import Image, ImageDraw
import random


class CaptchaWithBezier:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def random_color(self):
        """生成随机颜色"""
        return tuple(random.randint(0, 255) for _ in range(3))

    def random_number(self, min_value, max_value):
        """生成范围内的随机数"""
        return random.randint(min_value, max_value)

    def bezier_point(self, t, p0, p1, p2, p3=None):
        """
        计算贝塞尔曲线上的点
        t: 参数 (0 <= t <= 1)
        p0, p1, p2: 二阶贝塞尔曲线控制点
        p3: 三阶贝塞尔曲线控制点 (可选)
        """
        if p3 is None:  # 二阶贝塞尔曲线
            x = (1 - t) ** 2 * p0[0] + 2 * (1 - t) * t * p1[0] + t ** 2 * p2[0]
            y = (1 - t) ** 2 * p0[1] + 2 * (1 - t) * t * p1[1] + t ** 2 * p2[1]
        else:  # 三阶贝塞尔曲线
            x = (1 - t) ** 3 * p0[0] + 3 * (1 - t) ** 2 * t * p1[0] + 3 * (1 - t) * t ** 2 * p2[0] + t ** 3 * p3[0]
            y = (1 - t) ** 3 * p0[1] + 3 * (1 - t) ** 2 * t * p1[1] + 3 * (1 - t) * t ** 2 * p2[1] + t ** 3 * p3[1]
        return x, y

    def draw_bezier_curve(self, draw, num, color=None):
        """
        绘制随机贝塞尔曲线
        draw: ImageDraw 对象
        num: 曲线数量
        color: 曲线颜色
        """
        for _ in range(num):
            # 随机生成颜色
            curve_color = color if color else self.random_color()
            print(curve_color)

            # 随机生成控制点
            x1, y1 = 5, self.random_number(5, self.height // 2)
            x2, y2 = self.width - 5, self.random_number(self.height // 2, self.height - 5)
            ctrlx, ctrly = self.random_number(self.width // 4, self.width // 4 * 3), self.random_number(5, self.height - 5)

            if random.randint(0, 1):  # 二阶贝塞尔曲线
                points = [
                    self.bezier_point(t, (x1, y1), (ctrlx, ctrly), (x2, y2))
                    for t in [i / 20 for i in range(21)]
                ]
            else:  # 三阶贝塞尔曲线
                ctrlx1, ctrly1 = self.random_number(self.width // 4, self.width // 4 * 3), self.random_number(5, self.height - 5)
                points = [
                    self.bezier_point(t, (x1, y1), (ctrlx, ctrly), (ctrlx1, ctrly1), (x2, y2))
                    for t in [i / 20 for i in range(21)]
                ]

            # 绘制曲线
            for i in range(len(points) - 1):
                draw.line([points[i], points[i + 1]], fill=color if color else self.random_color(), width=2)

    def create_image(self):
        """创建带贝塞尔曲线的图像"""
        image = Image.new("RGB", (self.width, self.height), (255, 255, 255))
        draw = ImageDraw.Draw(image)

        # 绘制 5 条贝塞尔曲线
        self.draw_bezier_curve(draw, 5)

        return image


if __name__ == "__main__":
    # 示例用法
    captcha = CaptchaWithBezier(300, 100)
    image = captcha.create_image()
    image.show()

